<?php
/**
 * PrynLib
 * @copyright 2007-2009 Prynel
 * @author Olivier ROGER <roger.olivier@gmail.com>
 * @category libPrynel
 * @package Config
 * @version $Revision: 95 $
 */

/**
 * Class permettant la gestion de configuration via fichier ini.
 * /!\ Les fichiers ini ne doivent pas être accessible via le web.
 * @category libPrynel
 * @package Config
 * @version 1.1.1 
 * @author Olivier ROGER <roger.olivier@gmail.com>
 * @copyright  2007-2009 Prynel
 *       
 *
 */
class Config_Ini extends Config_Config
{
	/**
	 * Fichier à lire
	 *
	 * @var string
	 */
	private $file;
	
	/**
	 * Section spécifique à lire
	 *
	 * @var string
	 */
	private $section;
	
	/**
	 * Instance de classe
	 *
	 * @var Config_ini
	 */
	private static $instance 	= null;
	
	/**
	 * Constructeur
	 *
	 * @param string $file
	 * @param string $section
	 */
	public function __construct($file,$section)
	{
		if(file_exists($file))
		{
			$this->file = $file;
			$this->section = $section;
			$this->parseIni();
		}
		else
			throw new Util_ExceptionHandler('Fichier de configuration introuvable : '.$file);
	}
	
	/**
	 * Singleton
	 *
	 * @param Fichier à charger $file
	 * @param Section à lire $section
	 * @since 1.1.0
	 * @return Config_Ini
	 */
	public static function getInstance($file,$section=null)
 	{
 		if(!isset(self::$instance))
 		{
 			self::$instance = new Config_Ini($file,$section=null);
 		}
 		return self::$instance;
 	}
	/**
	 * Parse le fichier ini.
	 * Gère l'héritage de section via ':'
	 *
	 * @access private
	 */
	private function parseIni()
	{
		$iniFile = parse_ini_file($this->file,true);
		$sectionArray = array();
		foreach($iniFile as $key=>$value)
		{
			$section = explode(':',$key);
			$thisSection = trim($section[0]);
			switch(count($section))
			{
				case 1 :
					$sectionArray[$thisSection] = $value;
					break;
				case 2 :
					$parent = trim($section[1]);
					$sectionArray[$thisSection] = array_merge($sectionArray[$parent],$value);
					break;
				default :
					throw new Util_ExceptionHandler('Héritage multiple impossible');
					break;
			}
		}
		$this->parseSection($sectionArray);
		unset($sectionArray);
	}
	
	/**
	 * Tri par section sur le tableau extrait du fichier ini
	 *
	 * @param array $data
	 * @access private
	 */
	private function parseSection($data)
	{
		$filteredData = array();
		if($this->section!= null)
		{
			foreach($data as $section=>$value)
			{
				if(is_array($this->section))
				{
					if(in_array($section,$this->section))
						$filteredData[$section] = $value;
				}
				else
				{
					if($this->section == $section)
						$filteredData[$section] = $value;
				}
			}
		}
		else
		{
			$filteredData = $data;
		}
		unset($data);
		$this->parseKey($filteredData);
	}
	
	/**
	 * Parse les clés. Gère les "namespace" avec le caractère .
	 *
	 * @param array $filteredData
	 * @access private
	 */
	private function parseKey($filteredData)
	{
		$processedData 	= array();
		$namespace 		= array();
		foreach($filteredData as $section=>$value)
		{
			foreach($value as $cle=>$valeur)
			{
				$namespace = explode('.',$cle);
				$total = count($namespace);
				switch($total)
				{
					case 1:
						$processedData[$cle] = $valeur;
						break;
					case 2:
						if(!isset($processedData[$namespace[0]])) // !is_array() ?
							$processedData[$namespace[0]] = array();
						$processedData[$namespace[0]][$namespace[1]] = $valeur;
						break;
					default:
						break;
				}
			}
		}
		parent::__construct($processedData);
	}
}

